package com.example.sams.utils;

import java.util.Random;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;

/**
 * ID生成工具类
 * 用于生成数据库实体类的主键ID
 * 支持两种格式：
 * 1. 前缀+数字编号格式（如：u001, st001, c001等）
 * 2. UUID格式（32位十六进制字符串）
 *
 * @author jinghong
 * @since 2025-11-04
 */
public class UuidUtil {

    // 用于生成唯一序列号的原子计数器
    private static final AtomicLong sequenceCounter = new AtomicLong(0);
    private static final Random random = new Random();

    // ==================== 前缀+数字编号格式（推荐使用） ====================

    /**
     * 自动生成唯一ID（格式：前缀 + 3位随机数字编号）
     * 使用时间戳和随机数组合，确保唯一性
     * 例如：generateUniqueId("u") -> "u123"
     *      generateUniqueId("st") -> "st456"
     *
     * @param prefix 前缀（如：u, st, tc, c等）
     * @return 格式化的ID字符串
     */
    public static String generateUniqueId(String prefix) {
        long timestamp = System.currentTimeMillis();
        int randomValue = random.nextInt(1000); // 添加少量随机性
        return prefix + timestamp + randomValue;
    }


    /**
     * 自动生成唯一ID（可自定义数字位数）
     * 例如：generateUniqueId("u", 3) -> "u123"
     *      generateUniqueId("u", 4) -> "u0123"
     *
     * @param prefix 前缀
     * @param digits 数字位数（默认3位）
     * @return 格式化的ID字符串
     */
    public static String generateUniqueId(String prefix, int digits) {
        long timestamp = System.currentTimeMillis();
        int timePart = (int) (timestamp % 1000);
        int randomPart = random.nextInt(100);
        long seqPart = sequenceCounter.incrementAndGet() % 100;

        // 根据位数计算最大数值
        int maxValue = (int) Math.pow(10, digits) - 1;
        int uniqueNumber = (int) ((timePart * 100 + randomPart + seqPart) % maxValue) + 1;

        return String.format("%s%0" + digits + "d", prefix, uniqueNumber);
    }

    /**
     * 根据前缀和序号生成ID（格式：前缀 + 3位数字编号）
     * 例如：generateIdByPrefix("u", 1) -> "u001"
     *      generateIdByPrefix("st", 21) -> "st021"
     *
     * @param prefix 前缀（如：u, st, tc, c等）
     * @param sequence 序号（从1开始）
     * @return 格式化的ID字符串
     */
    public static String generateIdByPrefix(String prefix, int sequence) {
        return String.format("%s%03d", prefix, sequence);
    }

    /**
     * 根据前缀和序号生成ID（可自定义数字位数）
     * 例如：generateIdByPrefix("u", 1, 3) -> "u001"
     *      generateIdByPrefix("u", 1, 4) -> "u0001"
     *
     * @param prefix 前缀
     * @param sequence 序号
     * @param digits 数字位数（默认3位）
     * @return 格式化的ID字符串
     */
    public static String generateIdByPrefix(String prefix, int sequence, int digits) {
        return String.format("%s%0" + digits + "d", prefix, sequence);
    }

    // ==================== 各实体类型的便捷方法（自动生成唯一ID） ====================

    /**
     * 自动生成用户ID（格式：u001, u123, ...）
     * 无需手动输入序号，自动生成随机且唯一的ID
     *
     * @return 用户ID
     */
    public static String generateUserId() {
        return generateUniqueId("u");
    }

    /**
     * 自动生成学生ID（格式：st001, st456, ...）
     * 无需手动输入序号，自动生成随机且唯一的ID
     *
     * @return 学生ID
     */
    public static String generateStudentId() {
        return generateUniqueId("st");
    }

    /**
     * 自动生成教师ID（格式：tc001, tc789, ...）
     * 无需手动输入序号，自动生成随机且唯一的ID
     *
     * @return 教师ID
     */
    public static String generateTeacherId() {
        return generateUniqueId("tc");
    }

    /**
     * 自动生成管理员ID（格式：ad001, ad234, ...）
     * 无需手动输入序号，自动生成随机且唯一的ID
     *
     * @return 管理员ID
     */
    public static String generateAdminId() {
        return generateUniqueId("ad");
    }

    /**
     * 自动生成课程ID（格式：c001, c567, ...）
     * 无需手动输入序号，自动生成随机且唯一的ID
     *
     * @return 课程ID
     */
    public static String generateCourseId() {
        return generateUniqueId("c");
    }

    /**
     * 自动生成时间段ID（格式：ts001, ts890, ...）
     * 无需手动输入序号，自动生成随机且唯一的ID
     *
     * @return 时间段ID
     */
    public static String generateTimeSlotId() {
        return generateUniqueId("ts");
    }

    /**
     * 自动生成选课ID（格式：e001, e345, ...）
     * 无需手动输入序号，自动生成随机且唯一的ID
     *
     * @return 选课ID
     */
    public static String generateEnrollmentId() {
        return generateUniqueId("e");
    }

    /**
     * 自动生成课程审核ID（格式：r001, r678, ...）
     * 无需手动输入序号，自动生成随机且唯一的ID
     *
     * @return 课程审核ID
     */
    public static String generateCourseReviewId() {
        return generateUniqueId("r");
    }

    // ==================== 手动指定序号的方法（保留兼容性） ====================

    /**
     * 生成用户ID（格式：u001, u002, ...）
     *
     * @param sequence 序号
     * @return 用户ID
     */
    public static String generateUserId(int sequence) {
        return generateIdByPrefix("u", sequence);
    }

    /**
     * 生成学生ID（格式：st001, st002, ...）
     *
     * @param sequence 序号
     * @return 学生ID
     */
    public static String generateStudentId(int sequence) {
        return generateIdByPrefix("st", sequence);
    }

    /**
     * 生成教师ID（格式：tc001, tc002, ...）
     *
     * @param sequence 序号
     * @return 教师ID
     */
    public static String generateTeacherId(int sequence) {
        return generateIdByPrefix("tc", sequence);
    }

    /**
     * 生成管理员ID（格式：ad001, ad002, ...）
     *
     * @param sequence 序号
     * @return 管理员ID
     */
    public static String generateAdminId(int sequence) {
        return generateIdByPrefix("ad", sequence);
    }

    /**
     * 生成课程ID（格式：c001, c002, ...）
     *
     * @param sequence 序号
     * @return 课程ID
     */
    public static String generateCourseId(int sequence) {
        return generateIdByPrefix("c", sequence);
    }

    /**
     * 生成时间段ID（格式：ts001, ts002, ...）
     *
     * @param sequence 序号
     * @return 时间段ID
     */
    public static String generateTimeSlotId(int sequence) {
        return generateIdByPrefix("ts", sequence);
    }

    /**
     * 生成选课ID（格式：e001, e002, ...）
     *
     * @param sequence 序号
     * @return 选课ID
     */
    public static String generateEnrollmentId(int sequence) {
        return generateIdByPrefix("e", sequence);
    }

    /**
     * 生成课程审核ID（格式：r001, r002, ...）
     *
     * @param sequence 序号
     * @return 课程审核ID
     */
    public static String generateCourseReviewId(int sequence) {
        return generateIdByPrefix("r", sequence);
    }

    // ==================== UUID格式（备用） ====================

    /**
     * 生成标准UUID（带连字符，格式：xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx）
     * 例如：550e8400-e29b-41d4-a716-446655440000
     *
     * @return 标准格式的UUID字符串
     */
    public static String generateUuid() {
        return UUID.randomUUID().toString();
    }

    /**
     * 生成不带连字符的UUID（32位十六进制字符串）
     * 例如：550e8400e29b41d4a716446655440000
     *
     * @return 不带连字符的UUID字符串（小写）
     */
    public static String generateUuidWithoutHyphen() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 生成不带连字符的大写UUID（32位十六进制字符串）
     * 例如：550E8400E29B41D4A716446655440000
     *
     * @return 不带连字符的UUID字符串（大写）
     */
    public static String generateUuidUpperCase() {
        return generateUuidWithoutHyphen().toUpperCase();
    }

    /**
     * 生成不带连字符的小写UUID（32位十六进制字符串）
     * 与 generateUuidWithoutHyphen() 功能相同，但方法名更明确
     * 例如：550e8400e29b41d4a716446655440000
     *
     * @return 不带连字符的UUID字符串（小写）
     */
    public static String generateUuidLowerCase() {
        return generateUuidWithoutHyphen();
    }

    /**
     * 生成数据库主键ID（UUID格式）
     * 默认使用不带连字符的小写UUID，长度为32位，适合作为数据库主键
     *
     * @return 32位小写UUID字符串
     */
    public static String generateId() {
        return generateUuidWithoutHyphen();
    }
}

